package com.iot08.api.service;

import com.alibaba.fastjson.JSONObject;
import com.iot08.common.entity.app.AliPayNotifyInfo;
import com.iot08.common.service.base.BaseService;
import com.iot08.common.utils.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;

/**
 * @author cwj
 * @description
 * @date 2024/12/30 13:30
 **/
@Slf4j
@Service
public class AliPayNotifyInfoService extends BaseService<AliPayNotifyInfo> {


    /**
     * @description 保存或更新通知消息
     * @author cwj
     * @param [params, tradeStatus]
     * @return com.iot08.common.entity.app.AliPayNotifyInfo
     * @date @time 2024/12/30 15:52
     **/
    public JSONObject saveOrUpdateNotifyInfo(Map<String, String> params, String tradeStatus ){
        JSONObject jsonObject = new JSONObject();
        //是否之前已经收到了通知
        boolean beforeHasReceivedNotify = false;
        //根据支付订单和通知类型查询支付宝异步通知信息（支付通知、退款通知）
        Integer alipayNotifyType = 1;
        if(StringUtils.isNotEmpty(params.get("refund_fee")) && StringUtils.isNotEmpty(params.get("gmt_refund"))){
            alipayNotifyType = 2;
        }
        AliPayNotifyInfo aliPayNotifyInfo = queryAliPayNotifyInfoByOutTradeNo(params.get("out_trade_no"),alipayNotifyType);
        if(ObjectUtils.isEmpty(aliPayNotifyInfo)){
            aliPayNotifyInfo = new AliPayNotifyInfo();
            //通知消息赋值
            settingAliPayNotifyInfo(params,tradeStatus ,aliPayNotifyInfo,alipayNotifyType);
            this.save(aliPayNotifyInfo);
        } else {
            if("TRADE_SUCCESS".equals(aliPayNotifyInfo.getTradeStatus()) || "TRADE_FINISHED".equals(aliPayNotifyInfo.getTradeStatus()) || "TRADE_CLOSED".equals(aliPayNotifyInfo.getTradeStatus())) {
                beforeHasReceivedNotify = true;
            }
            //重新赋值通知消息
            settingAliPayNotifyInfo(params,tradeStatus ,aliPayNotifyInfo,alipayNotifyType);
            //更新数据
            Update update = new Update();
            settingAliPayNotifyInfoUpDate(params,tradeStatus,update);
            this.updateById(new ObjectId(aliPayNotifyInfo.getId()),update);
        }
        jsonObject.put("aliPayNotifyInfo",aliPayNotifyInfo);
        jsonObject.put("beforeHasReceivedNotify",beforeHasReceivedNotify);
        return jsonObject;
    }

    /**
     * @description 根据订单查询通知信息
     * @author cwj
     * @param [outTradeNo]
     * @return com.iot08.common.entity.app.AliPayNotifyInfo
     * @date @time 2025/1/7 13:54
     **/
    public AliPayNotifyInfo queryAliPayNotifyInfoByOutTradeNo(String outTradeNo,Integer alipayNotifyType) {
        Query query = new Query(Criteria.where("outTradeNo").is(outTradeNo).and("alipayNotifyType").is(alipayNotifyType)).limit(1);
        return this.findOne(query);
    }

    /**
     * @description 设置AliPayNotifyInfo对象
     * @author cwj
     * @param [params, aliPayNotifyInfo]
     * @return void
     * @date @time 2024/12/30 13:41
     **/
    private void settingAliPayNotifyInfo(Map<String, String> params, String tradeStatus, AliPayNotifyInfo aliPayNotifyInfo,Integer alipayNotifyType) {
        aliPayNotifyInfo.setNotifyTime(params.get("notify_time"));
        aliPayNotifyInfo.setNotifyType(params.get("notify_type"));
        aliPayNotifyInfo.setAlipayNotifyType(alipayNotifyType);
        aliPayNotifyInfo.setNotifyId(params.get("notify_id"));
        aliPayNotifyInfo.setSignType(params.get("sign_type"));
        aliPayNotifyInfo.setSign(params.get("sign"));
        aliPayNotifyInfo.setTradeNo(params.get("trade_no"));
        aliPayNotifyInfo.setAppid(params.get("app_id"));
        aliPayNotifyInfo.setOutTradeNo(params.get("out_trade_no"));
        aliPayNotifyInfo.setTradeStatus(tradeStatus);
        if(StringUtils.isNotEmpty(params.get("total_amount"))) {
            aliPayNotifyInfo.setTotalAmount(new BigDecimal(params.get("total_amount")));
        }
        if(StringUtils.isNotEmpty(params.get("receipt_amount"))) {
            aliPayNotifyInfo.setReceiptAmount(new BigDecimal(params.get("receipt_amount")));
        }
        if(StringUtils.isNotEmpty(params.get("out_biz_no"))) {
            aliPayNotifyInfo.setOutBizNo(params.get("out_biz_no"));
        }
        if(StringUtils.isNotEmpty(params.get("buyer_id")) || StringUtils.isNotEmpty(params.get("buyer_open_id"))) {
            aliPayNotifyInfo.setBuyerId(StringUtils.isNotEmpty(params.get("buyer_id"))?params.get("buyer_id"):params.get("buyer_open_id"));
        }
        if(StringUtils.isNotEmpty(params.get("buyer_logon_id"))) {
            aliPayNotifyInfo.setBuyerLogonId(params.get("buyer_logon_id"));
        }
        if(StringUtils.isNotEmpty(params.get("seller_id"))) {
            aliPayNotifyInfo.setSellerId(params.get("seller_id"));
        }
        if(StringUtils.isNotEmpty(params.get("seller_email"))) {
            aliPayNotifyInfo.setSellerEmail(params.get("seller_email"));
        }
        if(StringUtils.isNotEmpty(params.get("invoice_amount"))) {
            aliPayNotifyInfo.setInvoiceAmount(new BigDecimal(params.get("invoice_amount")));
        }
        if(StringUtils.isNotEmpty(params.get("buyer_pay_amount"))) {
            aliPayNotifyInfo.setBuyerPayAmount(new BigDecimal(params.get("buyer_pay_amount")));
        }
        if(StringUtils.isNotEmpty(params.get("point_amount"))){
            aliPayNotifyInfo.setPointAmount(new BigDecimal(params.get("point_amount")));
        }
        if(StringUtils.isNotEmpty(params.get("refund_fee"))) {
            aliPayNotifyInfo.setRefundFee(new BigDecimal(params.get("refund_fee")));
        }
        if(StringUtils.isNotEmpty(params.get("send_back_fee"))) {
            aliPayNotifyInfo.setSendBackFee(new BigDecimal(params.get("send_back_fee")));
        }
        if(StringUtils.isNotEmpty(params.get("subject"))) {
            aliPayNotifyInfo.setSubject(params.get("subject"));
        }
        if(StringUtils.isNotEmpty(params.get("body"))) {
            aliPayNotifyInfo.setBody(params.get("body"));
        }
        if(StringUtils.isNotEmpty(params.get("passback_params"))) {
            aliPayNotifyInfo.setPassbackParams(params.get("passback_params"));
        }
        if(StringUtils.isNotEmpty(params.get("gmt_create"))) {
            aliPayNotifyInfo.setGmtCreate(params.get("gmt_create"));
        }
        if(StringUtils.isNotEmpty(params.get("gmt_payment"))) {
            aliPayNotifyInfo.setGmtPayment(params.get("gmt_payment"));
        }
        if(StringUtils.isNotEmpty(params.get("gmt_refund"))) {
            aliPayNotifyInfo.setGmtRefund(params.get("gmt_refund"));
        }
        if(StringUtils.isNotEmpty(params.get("gmt_close"))) {
            aliPayNotifyInfo.setGmtClose(params.get("gmt_close"));
        }
        if(StringUtils.isNotEmpty(params.get("fund_bill_list"))) {
            aliPayNotifyInfo.setFundBillList(params.get("fund_bill_list"));
        }
        if(StringUtils.isNotEmpty(params.get("voucher_detail_list"))) {
            aliPayNotifyInfo.setVoucherDetailList(params.get("voucher_detail_list"));
        }
        aliPayNotifyInfo.setCreateTime(new Date());
        aliPayNotifyInfo.setUpdateTime(new Date());
    }


    /**
     * @description 设置更新更新同一个通知消息的更新对象
     * @author cwj
     * @param [params, tradeStatus, update]
     * @return void
     * @date @time 2024/12/30 14:44
     **/
    private void settingAliPayNotifyInfoUpDate(Map<String, String> params, String tradeStatus, Update update)  {
        update.set("notifyTime",params.get("notify_time"));
        update.set("notifyType",params.get("notify_type"));
        update.set("notifyId",params.get("notify_id"));
        update.set("signType",params.get("sign_type"));
        update.set("sign",params.get("sign"));
        update.set("tradeNo",params.get("trade_no"));
        update.set("outTradeNo",params.get("out_trade_no"));
        update.set("tradeStatus",tradeStatus);
        if(StringUtils.isNotEmpty(params.get("total_amount"))) {
            update.set("totalAmount", new BigDecimal(params.get("total_amount")));
        }
        if(StringUtils.isNotEmpty(params.get("receipt_amount"))) {
            update.set("receiptAmount", new BigDecimal(params.get("receipt_amount")));
        }
        if(StringUtils.isNotEmpty(params.get("out_biz_no"))){
            update.set("outBizNo",params.get("out_biz_no"));
        }
        if(StringUtils.isNotEmpty(params.get("buyer_id")) || StringUtils.isNotEmpty(params.get("buyer_open_id"))){
            update.set("buyerId",StringUtils.isNotEmpty(params.get("buyer_id"))?params.get("buyer_id"):params.get("buyer_open_id"));
        }
        if(StringUtils.isNotEmpty(params.get("buyer_logon_id"))){
            update.set("buyerLogonId",params.get("buyer_logon_id"));
        }
        if(StringUtils.isNotEmpty(params.get("seller_id"))){
            update.set("sellerId",params.get("seller_id"));
        }
        if(StringUtils.isNotEmpty(params.get("seller_email"))){
            update.set("sellerEmail",params.get("seller_email"));
        }
        if(StringUtils.isNotEmpty(params.get("invoice_amount"))){
            update.set("invoiceAmount",new BigDecimal(params.get("invoice_amount")));
        }
        if(StringUtils.isNotEmpty(params.get("buyer_pay_amount"))){
            update.set("buyerPayAmount",new BigDecimal(params.get("buyer_pay_amount")));
        }
        if(StringUtils.isNotEmpty(params.get("point_amount"))){
            update.set("pointAmount",new BigDecimal(params.get("point_amount")));
        }
        if(StringUtils.isNotEmpty(params.get("refund_fee"))){
            update.set("refundFee",new BigDecimal(params.get("refund_fee")));
        }
        if(StringUtils.isNotEmpty(params.get("send_back_fee"))){
            update.set("sendBackFee",new BigDecimal(params.get("send_back_fee")));
        }
        if(StringUtils.isNotEmpty(params.get("subject"))){
            update.set("subject",params.get("subject"));
        }
        if(StringUtils.isNotEmpty(params.get("body"))){
            update.set("body",params.get("body"));
        }
        if(StringUtils.isNotEmpty(params.get("passback_params"))){
            update.set("passbackParams",params.get("passback_params"));
        }
        if(StringUtils.isNotEmpty(params.get("gmt_create"))){
            update.set("gmtCreate",params.get("gmt_create"));
        }
        if(StringUtils.isNotEmpty(params.get("gmt_payment"))){
            update.set("gmtPayment",params.get("gmt_payment"));
        }
        if(StringUtils.isNotEmpty(params.get("gmt_refund"))){
            update.set("gmtRefund",params.get("gmt_refund"));
        }
        if(StringUtils.isNotEmpty(params.get("gmt_close"))){
            update.set("gmtClose",params.get("gmt_close"));
        }
        if(StringUtils.isNotEmpty(params.get("fund_bill_list"))){
            update.set("fundBillList",params.get("fund_bill_list"));
        }
        if(StringUtils.isNotEmpty(params.get("voucher_detail_list"))){
            update.set("voucherDetailList",params.get("voucher_detail_list"));
        }
        update.set("updateTime", DateUtil.getDate(new Date()));
    }

}
